package com.bjb.vr.common.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjb.vr.common.ao.UmsRoleAo;
import com.bjb.vr.common.constant.RoleConstants;
import com.bjb.vr.common.constant.ThreadLocalConstant;
import com.bjb.vr.common.constant.UmsMenuConstants;
import com.bjb.vr.common.dto.UmsOptMenu;
import com.bjb.vr.common.dto.UmsOptRole;
import com.bjb.vr.common.dto.UmsOptRoleMenu;
import com.bjb.vr.common.dto.UmsOptUserRole;
import com.bjb.vr.common.mapper.UmsOptMenuMapper;
import com.bjb.vr.common.mapper.UmsOptRoleMapper;
import com.bjb.vr.common.mapper.UmsOptRoleMenuMapper;
import com.bjb.vr.common.mapper.UmsOptUserRoleMapper;
import com.bjb.vr.common.utils.ThreadLocalUtil;
import com.bjb.vr.common.vo.MenuData;
import com.bjb.vr.common.vo.UmsAccountVo;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author admin
 * @description 针对表【ums_opt_menu(菜单权限表)】的数据库操作Service实现
 * @createDate 2022-08-23 08:44:51
 */
@Service
public class UmsOptMenuService extends ServiceImpl<UmsOptMenuMapper, UmsOptMenu> {

    @Resource
    private UmsOptMenuMapper optMenuMapper;

    @Resource
    private UmsOptRoleMapper optRoleMapper;

    @Resource
    private UmsOptUserRoleMapper optUserRoleMapper;

    @Resource
    private UmsOptRoleMenuMapper optRoleMenuMapper;

    /**
     * 查询首页
     *
     * @return
     */
    public List<MenuData> queryHomePage() {
        List<MenuData> newMenu = new ArrayList<>();
        // 查询用户信息
        UmsAccountVo umsAccountVo = (UmsAccountVo) ThreadLocalUtil.get(ThreadLocalConstant.USER_ACCOUNT_INFO);
        List<Long> roleIds = optUserRoleMapper.selectList(new LambdaQueryWrapper<UmsOptUserRole>().eq(UmsOptUserRole::getUserId, umsAccountVo.getUserId())).stream().map(UmsOptUserRole::getRoleId).collect(Collectors.toList());
        // 如果角色为空，说明没有分配角色
        if (CollectionUtils.isEmpty(roleIds)) {
            return newMenu;
        }
        // 判断是不是超级管理员
        List<UmsOptRole> optRoles = optRoleMapper.selectList(new LambdaQueryWrapper<UmsOptRole>().in(UmsOptRole::getRoleId, roleIds));
        Map<String, List<UmsOptRole>> listMap = optRoles.stream().collect(Collectors.groupingBy(UmsOptRole::getRoleKey));
        List<MenuData> menusLists = optMenuMapper.queryAllMenus();
        if (listMap.containsKey(RoleConstants.SUPER_ADMIN)) {
            // 获取菜单按钮集合
            UmsOptRole optRole = listMap.get(RoleConstants.SUPER_ADMIN).get(0);
            newMenu = queryMenus(menusLists, 0L, null, optRole, true);
        } else {
            // 获取菜单按钮集合
            List<UmsOptRoleMenu> roleMenus = optRoleMenuMapper.selectListByOptRoleId(roleIds.get(0), UmsMenuConstants.OPERATION);
            List<Long> authorizedMenuIds = roleMenus.stream().map(UmsOptRoleMenu::getMenuId).collect(Collectors.toList());
            UmsOptRole optRole = listMap.get(RoleConstants.COMMON).get(0);
            newMenu = queryMenus(menusLists, 0L, authorizedMenuIds, optRole, false);
        }
        return newMenu;
    }

    /**
     * 设置角色是否有权限
     *
     * @param umsOptRole
     * @param authorizedMenuIds
     * @param menuData
     */
    private void hasPrivilege(UmsOptRole umsOptRole, List<Long> authorizedMenuIds, MenuData menuData) {
        // 判断角色ID是否为空，为空说明新增角色权限
        if (Objects.isNull(umsOptRole) || Objects.isNull(umsOptRole.getRoleId())) {
            return;
        }
        // 如果是超级管理员--拥有所有权限
        if (umsOptRole.getRoleKey().equals(RoleConstants.SUPER_ADMIN)) {
            menuData.setHasAuthority(1);
            return;
        }
        // 其他角色权限，根据分配的决定
        if (Objects.isNull(authorizedMenuIds) || authorizedMenuIds.size() <= 0) {
            return;
        }
        authorizedMenuIds.stream().forEach(f -> {
            if (f.equals(menuData.getMenuId())) {
                menuData.setHasAuthority(1);
            }
        });
    }

    /**
     * 递归获取菜单
     *
     * @param menus
     * @param parentId
     * @param authorizedMenuIds
     * @param umsOptRole
     * @return
     */
    public List<MenuData> queryMenus(List<MenuData> menus, Long parentId, List<Long> authorizedMenuIds, UmsOptRole umsOptRole, boolean visible) {
        List<MenuData> result = new ArrayList<>();
        for (MenuData menu : menus) {
            if (menu.getParentId().equals(parentId)) {
                List<MenuData> subMenus = queryMenus(menus, menu.getMenuId(), authorizedMenuIds, umsOptRole, visible);
                menu.setChildrens(subMenus);
                hasPrivilege(umsOptRole, authorizedMenuIds, menu);
                // 设置是否显示
                if (visible) {
                    result.add(menu);
                } else {
                    if (menu.getHasAuthority().equals(1)) {
                        result.add(menu);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 查询权限菜单
     *
     * @param umsRoleAo
     * @return
     */
    public List<MenuData> queryMenus(UmsRoleAo umsRoleAo) {
        // 查询所有菜单列表
        List<MenuData> menusLists = optMenuMapper.queryAllMenus();
        // 查询角色权限列表
        List<UmsOptRoleMenu> roleMenus = optRoleMenuMapper.selectListByOptRoleId(umsRoleAo.getRoleId(), UmsMenuConstants.OPERATION);
        List<Long> authorizedMenuIds = roleMenus.stream().map(UmsOptRoleMenu::getMenuId).collect(Collectors.toList());
        UmsOptRole umsOptRole = optRoleMapper.selectById(umsRoleAo.getRoleId());
        // 获取菜单按钮集合
        List<MenuData> menuData = queryMenus(menusLists, 0L, authorizedMenuIds, umsOptRole, true);
        return menuData;
    }
}
